﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint.Administration;
using System.IO;
using System.Diagnostics;
using Microsoft.SharePoint;

namespace Macaw.Wss3.LookupFieldControlAdapter
{
    public class LookupFieldControlAdapterJobDefinition : SPJobDefinition
    {

        public const string JobName = "LookupFieldControlAdapterJob";
        private const string BROWSERFILENAME = "LookupFieldControlAdapter.browser";
        private const string APPBROWSER_FOLDER = "App_Browsers";

        public bool Installing
        {
            get
            {
                return (bool)this.Properties["Installing"];
            }
            set
            {
                this.Properties["Installing"] = value;
            }
        }

        public LookupFieldControlAdapterJobDefinition()
            : base()
        {
        }

        public LookupFieldControlAdapterJobDefinition(string jobName, SPService service, SPServer server, SPJobLockType targetType)
            : base(jobName, service, server, SPJobLockType.None)
        {
        }
        public LookupFieldControlAdapterJobDefinition(string jobName, SPWebApplication webApplication)
            : base(jobName, webApplication, null, SPJobLockType.None)
        {
            this.Title = "LookupFieldControlAdapter Job";
        }

        /// <summary>
        /// This method will touch files with the ".browser" extension to force ASP.NET to recompile.
        /// After recompiling the new ControlAdapters will be activated.
        /// </summary>
        /// <param name="path">Path of the folder of the .browser-files</param>
        private void TouchBrowserFiles(string path)
        {
            foreach (string filename in System.IO.Directory.GetFiles(path, "*.browser"))
            {
                System.IO.File.SetLastWriteTime(filename, DateTime.Now);
            }
        }

        /// <summary>
        /// This method will construct a path-string to the App_Browsers folder for the given Zone.
        /// </summary>
        /// <param name="settings">Zone settings</param>
        /// <returns>Physical path for the given zone</returns>
        private string ConstructAppBrowserPath(SPIisSettings settings)
        {
            string basePath = settings.Path.ToString();
            string destPath = Path.Combine(basePath, APPBROWSER_FOLDER);
            return destPath;
        }



        public override void Execute(Guid targetInstanceId)
        {
            try
            {
                SPWebApplication webApplication = this.WebApplication;
                if (Installing)
                {
                    #region Construct the contents for the .browser file
                    System.IO.Stream resource = this.GetType().Assembly.GetManifestResourceStream("Macaw.Wss3.LookupFieldControlAdapter.FeatureCode.LookupFieldControlAdapter.browser");
                    if (resource == null || !resource.CanRead)
                    {
                        throw new Exception("Unable to read the resourcefile");
                    }

                    System.IO.StreamReader reader = new System.IO.StreamReader(resource);
                    string browserContents = reader.ReadToEnd();
                    browserContents = browserContents.Replace("{707D9AE2-D892-448f-8DC4-4BBC2C95770D}", typeof(LookupFieldControlAdapter).FullName + ", " + typeof(LookupFieldControlAdapter).Assembly.FullName);
                    #endregion

                    foreach (SPUrlZone zone in webApplication.IisSettings.Keys)
                    {
                        // The settings of the IIS application to update
                        SPIisSettings settings = webApplication.IisSettings[zone];

                        string destPath = ConstructAppBrowserPath(settings);
                        string fullfilename = Path.Combine(destPath, BROWSERFILENAME);

                        SPSecurity.RunWithElevatedPrivileges(delegate()
                        {
                            EventLog.WriteEntry(this.GetType().FullName, string.Format("Writing the file \"{0}\"", fullfilename), EventLogEntryType.Information);
                        }
                        );

                        using (System.IO.FileStream file = new System.IO.FileStream(fullfilename, FileMode.Create, FileAccess.Write))
                        {
                            using (System.IO.StreamWriter writer = new System.IO.StreamWriter(file))
                            {
                                writer.Write(browserContents);
                                writer.Flush();
                            }
                        }

                        TouchBrowserFiles(destPath);
                    }
                }
                else
                {
                    foreach (SPUrlZone zone in webApplication.IisSettings.Keys)
                    {
                        // The settings of the IIS application to update
                        SPIisSettings settings = webApplication.IisSettings[zone];

                        string destPath = ConstructAppBrowserPath(settings);
                        string fullfilename = Path.Combine(destPath, BROWSERFILENAME);

                        if (System.IO.File.Exists(fullfilename))
                        {
                            SPSecurity.RunWithElevatedPrivileges(delegate
                                {
                                    EventLog.WriteEntry(this.GetType().FullName, string.Format("Removing the file \"{0}\"", fullfilename), EventLogEntryType.Information);
                                }
                            );
                            System.IO.File.Delete(fullfilename);
                        }
                        else
                        {
                            SPSecurity.RunWithElevatedPrivileges(delegate
                            {
                                EventLog.WriteEntry(this.GetType().FullName, string.Format("File \"{0}\" is not present, thus not deleted.", fullfilename), EventLogEntryType.Information);
                            }
                            );
                        }

                        TouchBrowserFiles(destPath);
                    }
                }
            }
            catch (Exception ex)
            {
                SPSecurity.RunWithElevatedPrivileges(delegate
                {
                    EventLog.WriteEntry(this.GetType().FullName, string.Format("Error running the Job.\r\n{0}", ex.ToString()), EventLogEntryType.Error);
                });

                throw;
            }
            base.Execute(targetInstanceId);
        }

    }
}
